package com.blustreaksw.cyclecoach.btle;

import java.util.UUID;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.util.Log;


public class BtleDiscoveryManager {
	
	private final boolean DEBUG_ENABLED = true;
	private void logDebug(String s) { if(DEBUG_ENABLED) Log.d(TAG, s); }
	private static final String TAG = "BtleDeviceDiscovery";
	
	/***********************************************************************
     * Interface that allows the caller to handle any Bluetooth LE devices
     * that are discovered while the scan is active.
     ***********************************************************************/
	public interface BtleDiscoveryManagerCallback {
		public void onDeviceFound(final BluetoothDevice device, final int rssi, final byte[] scanRecord);
	}
	
	BtleDeviceType mDeviceType;
	Context mAppContext;
	BtleDiscoveryManagerCallback mCallback;
	
	public BtleDiscoveryManager(BtleDeviceType type, Context c, BtleDiscoveryManagerCallback dmCb) {
		mDeviceType = type;
		mAppContext = c;
		mCallback = dmCb;
	}
	
	/***********************************************************************
     * Member variables used to handle connection and access to 
     * Bluetooth LE devices. 
     ***********************************************************************/
	private BluetoothManager mBTManager = null;
	private BluetoothAdapter mBTAdapter = null;
	
	/***********************************************************************
     * initBt(), isBtEnabled(), isBleAvailable()
     * 		Functions to get access to the Android Bluetooth service and
     * 		to check if Bluetooth radio is currently on and BT LE feature
     * 		is available on device.
     ***********************************************************************/
	public boolean initBt() {
		mBTManager = (BluetoothManager) mAppContext.getSystemService(Context.BLUETOOTH_SERVICE);
		if(mBTManager != null) {
			mBTAdapter = mBTManager.getAdapter();
		} else {
			logDebug("(initBt) Unable to access Android Bluetooth Service.");
		}
		
		return (mBTManager != null) && (mBTAdapter != null);
	}
	
	public boolean isBtEnabled() {
		if(!mBTAdapter.isEnabled()) {
			logDebug("(isBtEnabled) Bluetooth is disabled on device.");
			return false;
		}
		return true;
	}
	
	public boolean isBleAvailable() {
		boolean hasBle = mAppContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);
		if(hasBle && mBTManager != null && mBTAdapter != null) {
			return true;
		}
		else {
			logDebug("(isBleAvailable) Bluetooth LE is not available on this device.");
			return false;
		}
	}
	
	/***********************************************************************
     * Initiate a search for the device type specified in BtleDeviceType.
     ***********************************************************************/
	public void searchForDevices() {
		// Specify the service we require of any devices we find.
		final UUID[] uuids = new UUID[] { mDeviceType.serviceUUID() };
		
		// Start search, results returned in callback routine
		mBTAdapter.startLeScan(uuids, mDeviceFoundCallback);	
	}
	
	/***********************************************************************
     * Stop searching for BtleDevices.
     ***********************************************************************/
	public void stopSearchingForDevices() {
		mBTAdapter.stopLeScan(mDeviceFoundCallback);
		logDebug("(stopSearchingForDevices) Stopped searching for devices.");
	}
	
	/***********************************************************************
     * Callback definition required by BluetoothAdapter
     ***********************************************************************/
	private BluetoothAdapter.LeScanCallback mDeviceFoundCallback = new BluetoothAdapter.LeScanCallback() {
        @Override
        public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord) {
        	logDebug(String.format("(onLeScan) Found %s, address: %s", mDeviceType.toString(), device.getAddress()));
        	mCallback.onDeviceFound(device, rssi, scanRecord);
        }
    };

}
